stanfordfandomcom-20200214-history
Apture interface for adding links
=Apture Analysis= Jing Chen and Benjamin Bercovitz Background Apture is a service that allows you to add popup links to your blog or webpage, which can link to previews of other webpages, images, or videos. Once you register your blog on their site, you are given a piece of javascript to add to your blog. Then, you can add links to your blog by highlighting text while in editor mode (which requires signing in to apture). These links are displayed to other users viewing the site. We analyzed the process by which links are created using Apture. Interaction Structure You can create a link by either highlighting the text that you want to link or by clicking on a divider that appears between paragraphs. This opens up a popup where you can specify what the link should be. This info is sent to the server, and the page is updated to show the newly created link. All other visitors will then see this link and hovering over it will give a popup of the page, image, or video. In the sections below, we analyze how each step of the interaction is implemented, with a summary of the overall interaction at the very end. Adding Javascript Since Apture does not have direct control over the HTML sent to the browser, it must use Javascript to change the behavior. It does so by asking the user to add a small Javascript include to their page. In my case, the script sourced: http://www.apture.com/js/apture.js?siteToken=cNfyIkU This script then adds children to the DOM of the page that pull in four Javascript files from the Apture server. http://static.apture.com/media/editor.js?v=108 http://static.apture.com/media/monolithic.js?v=108 http://static.apture.com/media/core.js?v=108 http://static.apture.com/media/linker.js?v=108 These Javascript files are the same for all blogs using Apture. They manage the interactions for creating and displaying links. Core.js handles the basic initialization, monolithic.js contains many common functions, editor.js handles many of the editor interactions, and linker.js handles the popup for creating links. Selecting Text 1. Highlighting text Highlighting text causes a linker iframe to be displayed at a location below the text. The linker component connects to many sources that might contain related media, like youTube and Wikipedia and displays top search results for each. The user can then select the related media to show when other users hover above the selected text (which has now been turned into a link). When the apture global object is initialized in monolithic.js, a listener is added for the 'mouseup' event at the highest level using document.addEvent(). This listener closes any current linker iframes currently present, and calls userMadeSelection if the user is in edit mode. The function userMadeSelection defines a local variable, $10, that differs in class depending on which browser is used, since they use different methods for giving the current selection. It can either use W3Selection for the Mozilla window.getSelection() or IESelection for IE's document.selection. Both of these classes inherit from the abstract class CanonicalSelection. CanonicalSelection provides the functionality for getting information about the highlighted text. In particular, highlight() is interesting because it maintains the illusion to the user that the element is hightlighted by the cursor even after it loses its real position due to the linker popup opening. It does this by applying a CSS style to it that mimicks the real highlighting's look and feel. One limitation is that a link cannot be created across the contents of sibling tags (for obvious reasons). This is handled by CanonicalSelection's isSingleTextNode method, which simply compares the DOM nodes for the start and the end of selection. One interesting implementation innovation comes from this line in userMadeSelection(event, selection): $1O=apture.getSelection($1P); return $1O&&setTimeout(function(){apture.userMadeSelection($1N,$1O);},10); Since this function is being called from an event dispatcher, it should not do expensive work (like searching through element text) after changing the DOM state because the browser may not render the page again until the event returns. The event handler already dismissed the previous linker window, so this lets the change be rendered more quickly. This setTimeout() hack lets the caller return immediately and then reenter the function 10ms later from the timeout dispatcher. Thus this function is specially written to maintain a snappy user interface. For more on this subject see Joseph Smarr's 2007 talk. 2. Selecting Between Paragraphs In editor.js, a class is defined called BetweenPassageControl, which sets the initial appearance of the divider, and its animation. Upon loading the editor, the divider is inserted between all passages by the function _cd(). The BetweenPassageControl is shown and hidden by controlling the opacity property using Javascript mouse events. Clicking is managed by binding a function, _cs, to the 'click' event. If it finds valid information about the location, then _cs() adds a placeholder (a square with dotted borders, with the text "Embed Media" in the middle) in place of the BetweenPassageControl. _cy animates the Embed Media placeholder into place. onComplete for _cy is bound to _cz, which opens the linker popup (using getLinkerPopup()) as soon as the placeholder animation is done. The opening animation is performed by animateOpen(), from monolithic.js. The popup itself is created in monolithic.js, and used in several places, but the title and contents change depending on the application. Selecting a Link The related media is loaded by various APIs, by searching for the phrase on the relevant service. In the case of Wikipedia, it goes through "wikimedia/js/", and sends a request to this object. This is done live, after each search is typed, so there is some latency here. However, each service goes through a separate request, so the data for each service is loaded in parallel. The user can look at the first loaded one while the rest of the links load, so the perceived latency here is still acceptable. The data for each service is fetched all at once, but it limits the results to a few (usually less than five) items. Thus, even though the granularity is low, this does not slow down the loading by much. Because it is hard to predict what the user will search for, there is no prefetching of results. Various functions are called from there with the results of the search, eventually calling _16(). This function displays the search results: given the returned information, it creates the link elements, and sets relevant title and source URL. Clicking on the link element goes to a page with the information for that link filled out in editable text boxes. Clicking the "Link This Item" button calls the function setMediaItem() and starts the process of setting up the link with the server. Sending Information setMediaItem() calls a series of functions, but main work is done in _fA(). This first acquries information about the link selected using apture.linkProperties (apture is a global object created on page load, and linkProperties is set by the linker). It then sends this information about the link to the server using sendEncodedMessage(), which calls makeSenderEndpoint() with a payload. This is the main part that interacts with the server. Displaying a Created Link This is done similarly to the original popup: the included Javascript pulls in the links from the server, and hovering over the link gives the popup, using the timeouts and animation from before. For each link, a